﻿/* ==============================================================================
 * 功能描述：BackpackModule  
 * 
 * 创 建 者：郑镇泉
 * 
 * 创建日期：2016/4/7 17:19:35
 * ==============================================================================*/

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using ZZQFrameWork;
using Random = UnityEngine.Random;

/// <summary>
/// 物品类型
/// </summary>
public enum Enum_GoodsType
{
    None,
    Equip,//装备
    Consumables,//消耗品
    Material//材料
}

/// <summary>
/// 物品子类型
/// </summary>
public enum Enum_SubGoodsType
{
    None,
    Head=1,//头
    Necklace=2,//项链
    Clothes=3,//衣服
    Pants=4,//裤子
    Shoes=5,//鞋子
    Glove=6,//手套
    Weapon=7,//武器
    Ring=8//戒指
}

/// <summary>
/// 装备攻击速度类型
/// </summary>
public enum Enum_EquipAtkSpeedType
{
    Low,//缓慢
    Medium,//中速
    High//急速
}

/// <summary>
/// 物品使用需求
/// </summary>
public class RequirementData
{
    public int lv;
    public AttrData attr;

    public RequirementData(int lv, AttrData data)
    {
        this.lv = lv;
        attr = data;
    }
}

/// <summary>
/// 物品数据
/// </summary>
public class GoodsVO
{
    /// <summary>
    /// 实例化的时候系统分配的id
    /// </summary>
    public int uid;

    /// <summary>
    /// 物品id
    /// </summary>
    public int id;

    /// <summary>
    /// 物品名称
    /// </summary>
    public string name;

    /// <summary>
    /// 物品图标
    /// </summary>
    public string icon;

    /// <summary>
    /// 物品描述
    /// </summary>
    public string des;

    /// <summary>
    /// 攻击力
    /// </summary>
    public int attack;

    /// <summary>
    /// 攻速类型
    /// </summary>
    public Enum_EquipAtkSpeedType atkSpeedType;

    /// <summary>
    /// 防御力
    /// </summary>
    public int def;

    /// <summary>
    /// 魔法攻击力
    /// </summary>
    public int magicAttack;

    /// <summary>
    /// 魔法防御力
    /// </summary>
    public int magicDef;

    /// <summary>
    /// 攻速名称
    /// </summary>
    private string atkSpeedName;

    public string AtkSpeedName
    {
        get
        {
            switch (atkSpeedType)
            {
                    case Enum_EquipAtkSpeedType.Low:
                    atkSpeedName = "低速";break;
                    case Enum_EquipAtkSpeedType.Medium:
                        atkSpeedName = "中速"; break;
                    case Enum_EquipAtkSpeedType.High:
                        atkSpeedName = "高速"; break;
            }
            return atkSpeedName;
        }
    }

    /// <summary>
    /// 恢复hp
    /// </summary>
    public int recoveHp;

    /// <summary>
    /// 恢复mp
    /// </summary>
    public int recoveMp;

    /// <summary>
    /// 出售价格
    /// </summary>
    public int price;

    /// <summary>
    /// 物品数量
    /// </summary>
    public int count;

    /// <summary>
    /// 物品类型
    /// </summary>
    public Enum_GoodsType goodsType;

    /// <summary>
    /// 物品子类型
    /// </summary>
    public Enum_SubGoodsType subGoodsType;

    /// <summary>
    /// 物品包含属性
    /// </summary>
    public List<AttrData> attrDataList = new List<AttrData>();

    /// <summary>
    /// 使用条件
    /// </summary>
    public List<RequirementData> requirementDataList = new List<RequirementData>();

    ///// <summary>
    ///// 物品包含魔法属性
    ///// </summary>
    //public List<MagicAttrData> magicAttrDataList=new List<MagicAttrData>(); 

    ///// <summary>
    ///// 该data是否为空
    ///// </summary>
    //private bool isEmpty = true;

    /// <summary>
    /// 该数据属于哪个背包里面
    /// </summary>
    public Enum_BagType bagType;

    //public bool IsEmpty
    //{
    //    get { return isEmpty; }
    //    set
    //    {
    //        isEmpty = value;
    //        if (IsEmpty)
    //        {
    //            id = 0;
    //            name = String.Empty;
    //            icon = String.Empty;
    //            count = 0;
    //            goodsType = Enum_GoodsType.None;
    //            subGoodsType = Enum_SubGoodsType.None;
    //            attrDataList.Clear();
    //        }
    //    }
    //}

    public GoodsVO(GoodsConfigGoods goods)
    {
        id = int.Parse(goods.id);
        //还需增加goods类型，消耗品或者材料，这里简单设置为消耗品
        goodsType=Enum_GoodsType.Consumables;
        name = goods.name;
        icon = goods.icon;
        des = goods.des;
        recoveHp = int.Parse(goods.recoveHp);
        recoveMp = int.Parse(goods.recoveMp);
        price = int.Parse(goods.price);
        count = 1;
    }

    public GoodsVO(EquipConfigEquip equip)
    {
        id = int.Parse(equip.id);
        name = equip.name;
        icon = equip.icon;
        des = equip.des;
        goodsType=Enum_GoodsType.Equip;
        subGoodsType = (Enum_SubGoodsType) int.Parse(equip.type);
        attack = int.Parse(equip.atk);
        def = int.Parse(equip.def);
        magicAttack = int.Parse(equip.magicAtk);
        magicDef = int.Parse(equip.magicDef);
        price = int.Parse(equip.price);
        for (int i = 0; i < equip.attr.Length; i++)
        {
            EquipConfigEquipAttr attr = equip.attr[i];
            AttrData data=new AttrData((Enum_AttrType)int.Parse(attr.type),int.Parse(attr.value));
            attrDataList.Add(data);
        }
        for (int i = 0; i < equip.requirement.Length; i++)
        {
            EquipConfigEquipRequirement requirement = equip.requirement[i];
            RequirementData data = new RequirementData(int.Parse(requirement.lv), new AttrData((Enum_AttrType)int.Parse(requirement.attrType), int.Parse(requirement.attrValue)));
            requirementDataList.Add(data);
        }
        count = 1;
    }

    public string GetInfoShowTips()
    {
        string info="<color=red>"+name+"</color>" + "\n";
        if (recoveHp != 0) info += "HP+" + recoveHp + "\n";
        if (recoveMp != 0) info += "MP+" + recoveMp + "\n";
        info += des + "\n";
        info += "出售价格：" + price + "\n";
        if (attrDataList.Count > 0)
        {
            for (int i = 0; i < attrDataList.Count; i++)
            {
                AttrData attr = attrDataList[i];
                info += attr.attrName + "  +" + attr.attrValue + "\n";
            }
        }

        return info;
    }
}
public class BackpackModule : BaseModule
{
    /// <summary>
    /// 所有物品集合，一共5个背包，不同背包储存不同的物品
    /// </summary>
    //public Dictionary<Enum_BagType,List<GoodsVO>> goodsDic=new Dictionary<Enum_BagType, List<GoodsVO>>();
    //public List<GoodsVO> goodsList=new List<GoodsVO>(); 
    public Dictionary<Enum_BagType, List<GoodsVO>> goodsDic = new Dictionary<Enum_BagType, List<GoodsVO>>();

    /// <summary>
    /// 单个背包物品最大数量
    /// </summary>
    public int bagGoodsItemMaxCount = 14;

    /// <summary>
    /// 开启的背包数量
    /// </summary>
    public int openBagCount = 1;

    /// <summary>
    /// 总背包数量
    /// </summary>
    public int maxBagCount = 5;

    /// <summary>
    /// 锁住的背包数量
    /// </summary>
    public int lockBagCount { get { return maxBagCount - openBagCount; } }

    /// <summary>
    /// 生成物品id
    /// </summary>
    public int uidIndex = 0;

    public BackpackModule()
    {
        AutoRegister = true;//模块开启自动注册

        for (int i = 0; i < openBagCount; i++)//根据开启的背包数量初始化背包
        {
            Enum_BagType type = (Enum_BagType)i;
            List<GoodsVO> goods = new List<GoodsVO>();
            goodsDic.Add(type, goods);
        }

        #region 测试

        //string[] goodsData = new[] { "2010", "2007", "2009", "2005", "2008" };
        //string[] equipData = new string[] { "1001", "1002", "1003", "1005", "1073", "1215", "1189", "1200", };

        //for (int i = 0; i < 13; i++)
        //{
        //    GoodsVO good;
        //    if (i%2 == 0)
        //    {
        //        //GoodsConfig config = GoodsConfig.get(Random.Range(0, goodsData.Length));
        //        //good.goodsType=Enum_GoodsType.Consumables;
        //        //good.id = config.Id;
        //        //good.name = config.Name;
        //        //good.icon = config.Icon;
        //        //good.recoveHp = config.RecoveHp;
        //        //good.recoveMp = config.RecoveMp;
        //        //good.price = config.Price;
        //        GoodsConfigGoods goods = GoodsConfigProvider.Instance.GetGoodsById(Random.Range(1, 5));
        //        good=new GoodsVO(goods);
        //    }
        //    else
        //    {
        //        //EquipConfig config = EquipConfig.get(Random.Range(0, equipData.Length));
        //        //good.goodsType=Enum_GoodsType.Equip;
        //        //good.id = config.Id;
        //        //good.name = config.Name;
        //        //good.icon = config.Icon;
        //        //good.des = config.Des;
        //        //good.subGoodsType = (Enum_SubGoodsType) config.Type;
        //        //good.attack = config.Atk;
        //        //foreach (KeyValuePair<string, int> keyValuePair in config.Attr)
        //        //{
        //        //    Enum_AttrType type =
        //        //        (Enum_AttrType)Enum.Parse(typeof(Enum_AttrType), keyValuePair.Key);
        //        //    AttrData data = new AttrData(type, keyValuePair.Value);
        //        //    good.attrDataList.Add(data);
        //        //}
        //        //good.price = config.Price;
        //        GoodsConfigGoods equip = GoodsConfigProvider.Instance.GetGoodsById(Random.Range(1, 5));
        //        good = new GoodsVO(equip);
        //    }
        //    AddGoods(good);
        //}

        //for (int i = 0; i < 8; i++)
        //{
        //    GoodsVO vo = new GoodsVO();
        //    vo.goodsType = Enum_GoodsType.Equip;
        //    vo.subGoodsType = (Enum_SubGoodsType) Random.Range(1, 6);
        //    int id = Random.Range(1001, 1099);
        //    vo.icon = "EquipIcon" + id;
        //    vo.id = id;
        //    vo.attrDataList.Add(new AttrData((Enum_AttrType)Random.Range(0,10),5));
        //    AddGoods(vo);
        //}

        //int count = 0;
        //foreach (KeyValuePair<Enum_BagType, List<GoodsVO>> keyValuePair in goodsDic)
        //{
        //    List<GoodsVO> goods = keyValuePair.Value;
        //    if (goods != null)
        //    {
        //        count += goods.Count;
        //    }

        //}
        //Debug.Log("背包里有物品数量：" + count);

        #endregion

    }

    #region 从集合中获取物品

    /// <summary>
    /// 获取背包物品集合
    /// </summary>
    /// <returns></returns>
    public List<GoodsVO> GetGoodsList()
    {
        List<GoodsVO> list = new List<GoodsVO>();
        GoodsVO good;
        //找到所有背包中所有的物品集合
        foreach (KeyValuePair<Enum_BagType, List<GoodsVO>> keyValuePair in goodsDic)
        {
            List<GoodsVO> goodsList = keyValuePair.Value;
            for (int i = 0; i < goodsList.Count; i++)
            {
                good = goodsList[i];
                list.Add(good);
            }
        }
        return list;
    }

    /// <summary>
    /// 根据物品id获取对应的goods
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public GoodsVO GetGoodsVOById(int id)
    {
        foreach (KeyValuePair<Enum_BagType, List<GoodsVO>> keyValuePair in goodsDic)
        {
            List<GoodsVO> goodsList = keyValuePair.Value;
            for (int i = 0; i < goodsList.Count; i++)
            {
                if (goodsList[i].id == id)
                {
                    return goodsList[i];
                }
            }
        }
        return null;
    }

    /// <summary>
    /// 根据物品uid获取对应的物品信息
    /// </summary>
    /// <param name="uid"></param>
    /// <returns></returns>
    public GoodsVO GetGoodsVOByUid(int uid)
    {
        foreach (KeyValuePair<Enum_BagType, List<GoodsVO>> keyValuePair in goodsDic)
        {
            List<GoodsVO> goodsList = keyValuePair.Value;
            for (int i = 0; i < goodsList.Count; i++)
            {
                if (goodsList[i].uid == uid)
                {
                    return goodsList[i];
                }
            }
        }
        return null;
    }

    /// <summary>
    /// 根据背包类型获取背包中的所有物品
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public List<GoodsVO> GetGoodsByBagType(Enum_BagType type)
    {
        if (goodsDic.ContainsKey(type))
        {
            return goodsDic[type];
        }
        return null;
    }

    /// <summary>
    /// 根据物品id获取背包中所有的物品
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public List<GoodsVO> GetGoodsListVOById(int id)
    {
        foreach (KeyValuePair<Enum_BagType, List<GoodsVO>> keyValuePair in goodsDic)
        {
            List<GoodsVO> goodsList = keyValuePair.Value;
            for (int i = 0; i < goodsList.Count; i++)
            {
                if (goodsList[i].id == id)
                    return goodsList;
            }
        }
        return null;
    }

    /// <summary>
    /// 根据物品uid获取背包中所有的物品
    /// </summary>
    /// <param name="uid"></param>
    /// <returns></returns>
    public List<GoodsVO> GetGoodsListVOByUid(int uid)
    {
        foreach (KeyValuePair<Enum_BagType, List<GoodsVO>> keyValuePair in goodsDic)
        {
            List<GoodsVO> goodsList = keyValuePair.Value;
            for (int i = 0; i < goodsList.Count; i++)
            {
                if (goodsList[i].uid == uid)
                    return goodsList;
            }
        }
        return null;
    }

    /// <summary>
    /// 根据物品类型获取背包中的所有物品
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public List<GoodsVO> GetGoodsListVOByGoodsType(Enum_GoodsType type)
    {
        List<GoodsVO> list=new List<GoodsVO>();
        foreach (KeyValuePair<Enum_BagType, List<GoodsVO>> keyValuePair in goodsDic)
        {
            List<GoodsVO> goods = keyValuePair.Value;
            for (int i = 0; i < goods.Count; i++)
            {
                if (goods[i].goodsType == type)
                {
                    list.Add(goods[i]);
                }
            }
        }
        return list;
    } 

    /// <summary>
    /// 找到空的GoodsVO
    /// </summary>
    /// <returns></returns>
    public bool SetGoodsInBag(GoodsVO goods)
    {
        foreach (KeyValuePair<Enum_BagType, List<GoodsVO>> keyValuePair in goodsDic)
        {
            List<GoodsVO> goodsArr = keyValuePair.Value;
            if (goodsArr.Count < bagGoodsItemMaxCount)
            {
                goodsArr.Add(goods);
                return true;
            }
        }
        return false;
    }

    #endregion

    #region 增删改查

    /// <summary>
    /// 添加物品
    /// </summary>
    /// <param name="goods"></param>
    public void AddGoods(GoodsVO goods)
    {
        Debug.Log("添加物品的类型："+goods.goodsType+"物品名称："+goods.name+"物品id:"+goods.icon);
        //当物品类型不是装备类型的时候，需要查找背包中是否有该物品，有的话则堆叠
        if (goods.goodsType != Enum_GoodsType.Equip)
        {
            GoodsVO vo = GetGoodsVOById(goods.id);//根据物品id查找背包中是否有该物品
            if (vo != null)
            {
                //Debug.Log("找到想通的物品，直接增加");
                UpdateGoods(goods);
                return;
            }
        }
        //Debug.Log("没有过该物品，需要新增加");
        goods.uid = uidIndex;
        if (SetGoodsInBag(goods))
        {
            uidIndex++;
        //发送界面到panel界面增加物品
        EventDispatcher.TriggerEvent(Events.CharacterEvent.OnAddItem, goods);
        }
        else
            Debug.Log("物品添加失败");
    }

    /// <summary>
    /// 更新物品
    /// </summary>
    /// <param name="goods"></param>
    public void UpdateGoods(GoodsVO goods)
    {
        GoodsVO vo = GetGoodsVOById(goods.id);
        if (vo != null)
        {
            vo.count += goods.count;
            Debug.Log("当前物品数量："+vo.count);
            //发送消息，更新物品
            EventDispatcher.TriggerEvent(Events.CharacterEvent.OnUpdateItem, vo);
            return;
        }
        AddGoods(goods);
    }

    /// <summary>
    /// 移除物品
    /// </summary>
    /// <param name="goods"></param>
    /// <returns></returns>
    public bool RemoveGoods(GoodsVO goods,int count=1)
    {
        Debug.Log("需要移除的物品Uid:"+goods.uid);
        GoodsVO vo = GetGoodsVOByUid(goods.uid);
        if (vo != null)
        {
            if (goods.goodsType == Enum_GoodsType.Equip)
            {
                GetGoodsListVOByUid(vo.uid).Remove(vo);
                //发送消息，移除物品
                EventDispatcher.TriggerEvent(Events.CharacterEvent.OnRemoveItem, goods);
                return true;
            }
            if (vo.count < goods.count)
            {
                Debug.LogError("需要从包裹里移除的物品数量不足够！物品名称：" + goods.name);
                return false;
            }
            Debug.Log("当前有该物品数量：" + vo.count + ",需要移除数量：" + count);
            vo.count -= count;
            if (vo.count == 0)
            {
                Debug.Log("当前有该物品数量为零");
                GetGoodsListVOByUid(vo.uid).Remove(vo);
                EventDispatcher.TriggerEvent(Events.CharacterEvent.OnRemoveItem, vo);
                return true;
            }
            //发送消息，更新物品
            EventDispatcher.TriggerEvent(Events.CharacterEvent.OnUpdateItem, vo);
            return true;
        }
        Debug.LogError("在包裹里找不到该物品，物品名称：" + goods.name);
        return false;
    }

    #endregion

    #region 解锁背包

    /// <summary>
    /// 解锁
    /// </summary>
    public void UnLocked()
    {
        openBagCount++;
        //发送消息解锁
    }

    #endregion

    /// <summary>
    /// 使用物品
    /// </summary>
    /// <param name="goods"></param>
    public bool OnUseGoods(GoodsVO goods)
    {
        if (goods.goodsType == Enum_GoodsType.Equip)
        {
            Debug.Log("开始穿装备");
            ModuleManager.Instance.Get<CharacterModule>().mainRole.WearEquip(goods);
            return true;
        }
        if (goods.goodsType == Enum_GoodsType.Consumables)
        {
            if (!ModuleManager.Instance.Get<CharacterModule>().mainRole.CheckGoodsIsFulfilRequirements(goods))
            {
                Debug.Log("物品使用条件不满足");
                return false;
            }
            ModuleManager.Instance.Get<CharacterModule>().mainRole.RecoverHp(goods.recoveHp);
            ModuleManager.Instance.Get<CharacterModule>().mainRole.RecoverMp(goods.recoveMp);
            RemoveGoods(goods);
            //Debug.Log(goods.recoveHp+"---"+goods.recoveMp);
            EventDispatcher.TriggerEvent(Events.CharacterEvent.OnRefreshPlayerInfoPanel);
        }
            //材料使用，暂时无用
        return false;
    }

}